﻿using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using NewLife.Caching;
using NewLife.Redis.Core;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Reflection;
using System.Runtime.Intrinsics.Arm;
using WomanMotion.WebApi.Api.Controllers;
using WomanMotion.WebApi.Model.Dtos.Action;
using WomanMotion.WebApi.Model.Dtos.Authoritys;
using WomanMotion.WebApi.Model.Dtos.Controller;
using WomanMotion.WebApi.Model.Entitys;
using WomanMotion.WebApi.Service.IService;
using WomanMotion.WebApi.Service.Service;

namespace WomanMotion.WebApi.Api.Utility
{
    /// <summary>
    /// 定义系统初始化类
    /// </summary>
    public static class InItializeSystem
    {
        /// <summary>
        /// 自定义系统初始化比如加载缓存
        /// </summary>
        /// <param name="endpoints"></param>
        /// <param name="common">系统公共服务</param>
        public static async void InItSystem(this IEndpointRouteBuilder app)
        {
            //endpoints
            var commonservices = app.ServiceProvider.GetService<ICommonService>();
            var controllerService = app.ServiceProvider.GetService<IControllerService>();
            var actionsService = app.ServiceProvider.GetService<IActionsService>();
            var authoritysService = app.ServiceProvider.GetService<IAuthoritysService>();
            var roleService = app.ServiceProvider.GetService<IRoleService>();
            var redisService = app.ServiceProvider.GetService<INewLifeRedis>();
            var usersService = app.ServiceProvider.GetService<IUsersService>();
            //获取所有控制器
            var assembly = typeof(Program).Assembly.GetTypes().AsEnumerable()
            .Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToList().Where(type => type.Name != "BaseController").ToList();
            //存储所有控制器的主键id
            List<long> connList = new List<long>();
            //存储所有方法的主键id
            List<long> actidsList = new List<long>();
            //循环控制器
            foreach (var assemblyType in assembly)
            {
                var decab = assemblyType.GetTypeInfo().GetCustomAttribute<DescriptionNameAttribute>();
                //获取自定义特性的存在的名字
                var classdescname = decab.Name;
                var connlname = assemblyType.Name.Replace("Controller", "");
                var createdControllerDTO = new CreatedControllerDTO();
                createdControllerDTO.Name = classdescname;
                createdControllerDTO.Code = connlname;
                //判断是否是路由
                if (decab != null && decab.IsRoute)
                {
                    //是前端路由
                    createdControllerDTO.Path = "/"+ connlname.ToLower()+","+ decab.Rank;
                }
                else
                {
                    //不是前端路由
                    createdControllerDTO.Path = "";
                }
                //控制器插入数据库
                var resconnl = await controllerService.CreatedAsync(createdControllerDTO, m => m.Code == connlname);
                //记录控制器表id
                long connlid = resconnl.Id;
                //控制器的ID存入集合
                connList.Add(connlid);
                //遍历控制器的方法
                var mets = assemblyType.GetMethods();
                foreach (var met in mets)
                {
                    //var test = met.Name;
                    var metdesc = met.GetCustomAttribute<DescriptionNameAttribute>();
                    if (metdesc != null)
                    {
                        var actdescname = metdesc.Name;
                        var actname = met.Name;
                        var createdActionsDTO = new CreatedActionsDTO();
                        createdActionsDTO.Name = actdescname;
                        createdActionsDTO.Code = actname;
                        createdActionsDTO.Controllerid = connlid;
                        //判断是否是路由
                        if (metdesc.IsRoute)
                        {
                            //是前端路由
                            createdActionsDTO.Path = "/" + connlname.ToLower() + "/" + metdesc.RoutePath.ToLower()+","+ metdesc.RouteTitle+","+ metdesc.RouteCode;
                        }
                        else
                        {
                            //不是前端路由
                            createdActionsDTO.Path = "";
                        }
                        //方法插入数据库
                        var resaction = await actionsService.CreatedAsync(createdActionsDTO, m => m.Code == actname && m.Controllerid == connlid);
                        //方法插入权限表给admin角色分配权限
                        //查询admin角色id
                        var roleentity = await roleService.GetAsync(m => m.Code == "admin");
                        var roleid = roleentity.Id;
                        await authoritysService.CreatedAsync(new CreatedAuthoritysDTO() { Roleid = roleid, Controllerid = connlid, Actionsid = resaction.Id }, m => m.Roleid == roleid && m.Controllerid == connlid && m.Actionsid == resaction.Id);
                        //方法id添加到集合里面
                        actidsList.Add(resaction.Id);
                    }
                }
            }
            //清除控制器表脏数据
            await controllerService.DeleteAsync(m => !connList.Contains(m.Id));
            //清除方法表脏数据
            await actionsService.DeleteAsync(m => !connList.Contains(m.Controllerid));
            await actionsService.DeleteAsync(m => !actidsList.Contains(m.Id));
            //清除权限表脏数据
            await authoritysService.DeleteAsync(m => !connList.Contains(m.Controllerid));
            await authoritysService.DeleteAsync(m => !actidsList.Contains(m.Actionsid));
            //查询所有角色
            var roles = await roleService.GetListAsync();
            List<long> roleids = new List<long>();
            foreach (var role in roles)
            {
                //所有角色信息并把禁用状态加入缓存
                var redisname = "role_ifdisable_" + role.Code;
                var redisvalue = role.Ifdisable.ToString();
                //如果存在缓存先移除
                redisService.Remove(redisname);
                //然后在添加保证是最新
                redisService.Set(redisname, redisvalue);
                roleids.Add(role.Id);
            }
            await authoritysService.DeleteAsync(m => !roleids.Contains(m.Roleid));
            //查询所有权限并加入缓存
            var atths = await authoritysService.GetAuthoritysListAsync();
            foreach (var atth in atths)
            {
                var redisname = "auth_" + atth.RoleCode + "_" + atth.ControllerCode + "_" + atth.ActionsCode;
                var redisvalue = new AuthoritysReids() { RoleCode = atth.RoleCode, ControllerCode = atth.ControllerCode, ActionsCode = atth.ActionsCode };
                //如果存在缓存先移除
                redisService.Remove(redisname);
                //然后在添加保证是最新权限
                redisService.Set(redisname, redisvalue);
            }
            //查询所有用户信息并把禁用状态和用户所属的角色加入缓存
            var users = await usersService.GetListAsync();
            foreach (var item in users)
            {
                //用户的禁用状态加入缓存
                var redisuserdisablename = "user_ifdisable_" + item.Id;
                var redisuserdisablevalue = item.Ifdisable.ToString();
                //如果存在缓存先移除
                redisService.Remove(redisuserdisablename);
                //然后在添加保证是最新
                redisService.Set(redisuserdisablename, redisuserdisablevalue);
                //用户所属的角色加入缓存
                var redisuserrolename = "user_rolecode_" + item.Id;
                //根据角色id查询角色代码
                var rolevm = await roleService.GetAsync(m => m.Id == item.Roleid);
                var redisuserrolevalue = rolevm.Code;
                //如果存在缓存先移除
                redisService.Remove(redisuserrolename);
                //然后在添加保证是最新
                redisService.Set(redisuserrolename, redisuserrolevalue);
            }
        }
    }
}